/**
 * @create 2022-04-14
 * @desc 表格的配置 context
 */

import type { FC, Dispatch, Reducer } from 'react';
import React, { createContext, useContext, useEffect, useMemo, useReducer } from 'react';
import { PaginationProps } from 'antd';
import { Result } from 'ahooks/lib/useRequest/src/types';

export interface State {
  params?: Record<string, any>;
  pagination?: {
    current?: number;
    pageSize?: number;
  };
}
export type Action =
  | {
      type: 'updateParams';
      payload: Record<string, any>;
    }
  | {
      type: 'onPaginationChange';
      payload: {
        current: number;
        pageSize: number;
      };
    }
  | {
      type: 'updateRequest';
      payload: Result<any, any>;
    };

const baseState: State = {
  pagination: {
    current: 1,
    pageSize: 20,
  },
};

interface ProTableStoreType {
  state: State;
  dispatch: Dispatch<Action>;
}

export const ProTableStore = createContext<ProTableStoreType>({
  state: baseState,
  dispatch: () => ({}),
});

const reducerFn: Reducer<State, Action> = (prevState, action) => {
  switch (action.type) {
    case 'updateParams':
      return {
        ...prevState,
        params: action.payload,
      };

    case 'updateRequest':
      return {
        ...prevState,
        request: action.payload,
      };

    case 'onPaginationChange':
      return {
        ...prevState,
        pagination: {
          ...prevState.pagination,
          ...action.payload,
        },
      };

    default:
      return prevState;
  }
};

export interface ProTableStoreProviderProps {
  pagination?: PaginationProps | false;
  params?: Record<string, any>;
}
export const ProTableStoreProvider: FC<ProTableStoreProviderProps> = ({
  children,
  pagination,
  params,
}) => {
  const initState: State = useMemo(() => {
    return {
      ...baseState,
      params,
      pagination:
        typeof pagination === 'boolean' && pagination === false
          ? {}
          : {
              current: pagination?.current || baseState?.pagination?.current,
              pageSize:
                pagination?.defaultPageSize ||
                pagination?.pageSize ||
                baseState?.pagination?.pageSize,
            },
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  const [pageState, dispatch] = useReducer(reducerFn, initState);
  const contextValue = useMemo(
    () => ({
      state: pageState,
      dispatch,
    }),
    [pageState, dispatch],
  );

  useEffect(() => {
    dispatch({
      type: 'updateParams',

      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
      payload: params!,
    });
  }, [params]);

  return <ProTableStore.Provider value={contextValue}>{children}</ProTableStore.Provider>;
};

export const useProTableStoreDispatch = () => {
  const tableContext = useContext(ProTableStore);

  return tableContext.dispatch;
};

export const useProTableStore = () => {
  const tableContext = useContext(ProTableStore);

  return tableContext.state;
};
